//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.0
#include "fsmc8080_bsp.h"

#if defined(STM32F40_41xxx) || defined(STM32F412xG) || defined(STM32F413_423xx)
#define GPIO_AF   AFIO_FSMC
#elif defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)
#define GPIO_AF   AFIO_FMC
#endif

static WHT_FSMC8080_Info_t WHT_LCD8080_Info;

/*FSMC8080 GPIO初始化*/
static void WHT_FSMC8080_BSP_GPIO_Init(void)
{
    //FSMC数据
#if (FSMC8080_Data_Width_bit >= 8)
    WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D0_PORT, ENABLE);                  WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D1_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D2_PORT, ENABLE);                  WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D3_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D4_PORT, ENABLE);                  WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D5_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D6_PORT, ENABLE);                  WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D7_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D0_PORT, FSMC_D0_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D1_PORT, FSMC_D1_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D2_PORT, FSMC_D2_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D3_PORT, FSMC_D3_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D4_PORT, FSMC_D4_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D5_PORT, FSMC_D5_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D6_PORT, FSMC_D6_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D7_PORT, FSMC_D7_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D0_PORT, FSMC_D0_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D1_PORT, FSMC_D1_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D2_PORT, FSMC_D2_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D3_PORT, FSMC_D3_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D4_PORT, FSMC_D4_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D5_PORT, FSMC_D5_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D6_PORT, FSMC_D6_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D7_PORT, FSMC_D7_PIN, GPIO_AF);
#endif
#if (FSMC8080_Data_Width_bit >= 16)
    WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D8_PORT, ENABLE);                    WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D9_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D10_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D11_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D12_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D13_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D14_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D15_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D8_PORT, FSMC_D8_PIN, Mode_AF_PP);    WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D9_PORT, FSMC_D9_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D10_PORT, FSMC_D10_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D11_PORT, FSMC_D11_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D12_PORT, FSMC_D12_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D13_PORT, FSMC_D13_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D14_PORT, FSMC_D14_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D15_PORT, FSMC_D15_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D8_PORT, FSMC_D8_PIN, GPIO_AF);       WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D9_PORT, FSMC_D9_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D10_PORT, FSMC_D10_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D11_PORT, FSMC_D11_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D12_PORT, FSMC_D12_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D13_PORT, FSMC_D13_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D14_PORT, FSMC_D14_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D15_PORT, FSMC_D15_PIN, GPIO_AF);
#endif
#if (FSMC8080_Data_Width_bit >= 32)
    WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D16_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D17_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D18_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D19_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D20_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D21_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D22_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D23_PORT, ENABLE);
    WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D24_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D25_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D26_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D27_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D28_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D29_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D30_PORT, ENABLE);                   WHT_GPIO_BSP.WHT_Set_Clock(FSMC_D31_PORT, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D16_PORT, FSMC_D16_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D17_PORT, FSMC_D17_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D18_PORT, FSMC_D18_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D19_PORT, FSMC_D19_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D20_PORT, FSMC_D20_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D21_PORT, FSMC_D21_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D22_PORT, FSMC_D22_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D23_PORT, FSMC_D23_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D24_PORT, FSMC_D24_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D25_PORT, FSMC_D25_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D26_PORT, FSMC_D26_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D27_PORT, FSMC_D27_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D28_PORT, FSMC_D28_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D29_PORT, FSMC_D29_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D30_PORT, FSMC_D30_PIN, Mode_AF_PP);  WHT_GPIO_BSP.WHT_Set_Mode(FSMC_D31_PORT, FSMC_D31_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D16_PORT, FSMC_D16_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D17_PORT, FSMC_D17_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D18_PORT, FSMC_D18_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D19_PORT, FSMC_D19_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D20_PORT, FSMC_D20_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D21_PORT, FSMC_D21_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D22_PORT, FSMC_D22_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D23_PORT, FSMC_D23_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D24_PORT, FSMC_D24_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D25_PORT, FSMC_D25_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D26_PORT, FSMC_D26_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D27_PORT, FSMC_D27_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D28_PORT, FSMC_D28_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D29_PORT, FSMC_D29_PIN, GPIO_AF);
	WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D30_PORT, FSMC_D30_PIN, GPIO_AF);     WHT_GPIO_BSP.WHT_Set_AFIO(FSMC_D31_PORT, FSMC_D31_PIN, GPIO_AF);
#endif
    //FSMC片选
    WHT_GPIO_BSP.WHT_Set_Clock(LCD_CS_PORT, ENABLE);
    WHT_GPIO_BSP.WHT_Set_Mode(LCD_CS_PORT, LCD_CS_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_AFIO(LCD_CS_PORT, LCD_CS_PIN, GPIO_AF);
    //FSMC地址
    WHT_GPIO_BSP.WHT_Set_Clock(LCD_DC_PORT, ENABLE);
    WHT_GPIO_BSP.WHT_Set_Mode(LCD_DC_PORT, LCD_DC_PIN, Mode_AF_PP);
    //写使能
    WHT_GPIO_BSP.WHT_Set_Clock(LCD_WR_PORT, ENABLE);
    WHT_GPIO_BSP.WHT_Set_Mode(LCD_WR_PORT, LCD_WR_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_AFIO(LCD_WR_PORT, LCD_WR_PIN, GPIO_AF);
    //读使能
    WHT_GPIO_BSP.WHT_Set_Clock(LCD_RD_PORT, ENABLE);
    WHT_GPIO_BSP.WHT_Set_Mode(LCD_RD_PORT, LCD_RD_PIN, Mode_AF_PP);
	WHT_GPIO_BSP.WHT_Set_AFIO(LCD_RD_PORT, LCD_RD_PIN, GPIO_AF);
}
/*FSMC8080配置*/
static void WHT_FSMC8080_BSP_Config(void)
{
#if defined(STM32F40_41xxx) || defined(STM32F412xG) || defined(STM32F413_423xx)
	FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStruct;
	FSMC_NORSRAMTimingInitTypeDef  FSMC_ReadWriteTimingStruct;

	/*使能FSMC外设时钟*/
	RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);

	//地址建立时间（ADDSET）为1个HCLK 2/168M=12ns
	FSMC_ReadWriteTimingStruct.FSMC_AddressSetupTime = 1;	
	//数据保持时间（DATAST）+ 1个HCLK = 5/168M=30ns
	FSMC_ReadWriteTimingStruct.FSMC_DataSetupTime = 4;
	//地址保持时间（ADDHLD）模式B未用到
	FSMC_ReadWriteTimingStruct.FSMC_AddressHoldTime = 0;
	//设置总线转换周期，仅用于复用模式的NOR操作
	FSMC_ReadWriteTimingStruct.FSMC_BusTurnAroundDuration = 0;
	//设置时钟分频，仅用于同步类型的存储器
	FSMC_ReadWriteTimingStruct.FSMC_CLKDivision = 0;
	//数据保持时间，仅用于NOR
	FSMC_ReadWriteTimingStruct.FSMC_DataLatency = 0;
	//模式B,异步NOR FLASH模式，与LCD的8080时序匹配
	FSMC_ReadWriteTimingStruct.FSMC_AccessMode = FSMC_AccessMode_B;
    
	// 选择FSMC映射的存储区域： Bank1 NORSRAMx
	FSMC_NORSRAMInitStruct.FSMC_Bank = FSMC_Bank1_NORSRAM1;
	//设置地址总线与数据总线是否复用，仅用于NOR
	FSMC_NORSRAMInitStruct.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
	//设置要控制的存储器类型：NOR类型
	FSMC_NORSRAMInitStruct.FSMC_MemoryType =FSMC_MemoryType_NOR;
	//存储器数据宽度：16位
#if (FSMC8080_Data_Width_bit == 8)
	RSRAMInitStruct.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
#elif (FSMC8080_Data_Width_bit == 16)
    FSMC_NORSRAMInitStruct.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
#else
    return;
#endif
	//设置是否使用突发访问模式，仅用于同步类型的存储器
	FSMC_NORSRAMInitStruct.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;
	//设置是否使能等待信号，仅用于同步类型的存储器
	FSMC_NORSRAMInitStruct.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
	//设置等待信号的有效极性，仅用于同步类型的存储器
	FSMC_NORSRAMInitStruct.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
	//设置是否支持把非对齐的突发操作，仅用于同步类型的存储器
	FSMC_NORSRAMInitStruct.FSMC_WrapMode = FSMC_WrapMode_Disable; 
	//设置等待信号插入的时间，仅用于同步类型的存储器
	FSMC_NORSRAMInitStruct.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
	//存储器写使能 
	FSMC_NORSRAMInitStruct.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
	//不使用等待信号
	FSMC_NORSRAMInitStruct.FSMC_WaitSignal = FSMC_WaitSignal_Disable;  		
	// 不使用扩展模式，读写使用相同的时序
	FSMC_NORSRAMInitStruct.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; 
	//突发写操作
	FSMC_NORSRAMInitStruct.FSMC_WriteBurst = FSMC_WriteBurst_Disable;  
	//读写时序配置
	FSMC_NORSRAMInitStruct.FSMC_ReadWriteTimingStruct = &FSMC_ReadWriteTimingStruct;
	//读写同样时序，使用扩展模式时这个配置才有效
	FSMC_NORSRAMInitStruct.FSMC_WriteTimingStruct = &FSMC_ReadWriteTimingStruct; 

	FSMC_NORSRAMInit(&FSMC_NORSRAMInitStruct);                 //初始化FSMC配置
	FSMC_NORSRAMCmd(FSMC_NORSRAMInitStruct.FSMC_Bank, ENABLE); //使能BANK
#elif defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)
	FMC_NORSRAMInitTypeDef  FMC_NORSRAMInitStruct;
	FMC_NORSRAMTimingInitTypeDef  FMC_ReadWriteTimingStruct;

	/*使能FSMC外设时钟*/
	RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);

	//地址建立时间（ADDSET）为1个HCLK 2/180M=12ns
	FMC_ReadWriteTimingStruct.FMC_AddressSetupTime = 1;	
	//数据保持时间（DATAST）+ 1个HCLK = 5/180M=30ns
	FMC_ReadWriteTimingStruct.FMC_DataSetupTime = 4;
	//地址保持时间（ADDHLD）模式B未用到
	FMC_ReadWriteTimingStruct.FMC_AddressHoldTime = 0;
	//设置总线转换周期，仅用于复用模式的NOR操作
	FMC_ReadWriteTimingStruct.FMC_BusTurnAroundDuration = 0;
	//设置时钟分频，仅用于同步类型的存储器
	FMC_ReadWriteTimingStruct.FMC_CLKDivision = 0;
	//数据保持时间，仅用于NOR
	FMC_ReadWriteTimingStruct.FMC_DataLatency = 0;
	//模式B,异步NOR FLASH模式，与LCD的8080时序匹配
	FMC_ReadWriteTimingStruct.FMC_AccessMode = FMC_AccessMode_B;
    
	// 选择FSMC映射的存储区域： Bank1 NORSRAMx
	FMC_NORSRAMInitStruct.FMC_Bank = FMC_Bank1_NORSRAM1;
	//设置地址总线与数据总线是否复用，仅用于NOR
	FMC_NORSRAMInitStruct.FMC_DataAddressMux = FMC_DataAddressMux_Disable;
	//设置要控制的存储器类型：NOR类型
	FMC_NORSRAMInitStruct.FMC_MemoryType =FMC_MemoryType_NOR;
	//存储器数据宽度：16位
#if (FSMC8080_Data_Width_bit == 8)
	FMC_NORSRAMInitStruct.FMC_MemoryDataWidth = FMC_NORSRAM_MemoryDataWidth_8b;
#elif (FSMC8080_Data_Width_bit == 16)
    FMC_NORSRAMInitStruct.FMC_MemoryDataWidth = FMC_NORSRAM_MemoryDataWidth_16b;
#elif (FSMC8080_Data_Width_bit == 32)
	FMC_NORSRAMInitStruct.FMC_MemoryDataWidth = FMC_NORSRAM_MemoryDataWidth_32b;
#else
	return;
#endif
	//设置是否使用突发访问模式，仅用于同步类型的存储器
	FMC_NORSRAMInitStruct.FMC_BurstAccessMode =FMC_BurstAccessMode_Disable;
	//设置是否使能等待信号，仅用于同步类型的存储器
	FMC_NORSRAMInitStruct.FMC_AsynchronousWait=FMC_AsynchronousWait_Disable;
	//设置等待信号的有效极性，仅用于同步类型的存储器
	FMC_NORSRAMInitStruct.FMC_WaitSignalPolarity = FMC_WaitSignalPolarity_Low;
	//设置是否支持把非对齐的突发操作，仅用于同步类型的存储器
	FMC_NORSRAMInitStruct.FMC_WrapMode = FMC_WrapMode_Disable; 
	//设置等待信号插入的时间，仅用于同步类型的存储器
	FMC_NORSRAMInitStruct.FMC_WaitSignalActive = FMC_WaitSignalActive_BeforeWaitState;
	//存储器写使能 
	FMC_NORSRAMInitStruct.FMC_WriteOperation = FMC_WriteOperation_Enable;
	//不使用等待信号
	FMC_NORSRAMInitStruct.FMC_WaitSignal = FMC_WaitSignal_Disable;  		
	// 不使用扩展模式，读写使用相同的时序
	FMC_NORSRAMInitStruct.FMC_ExtendedMode = FMC_ExtendedMode_Disable; 
	//突发写操作
	FMC_NORSRAMInitStruct.FMC_WriteBurst = FMC_WriteBurst_Disable;  
	//读写时序配置
	FMC_NORSRAMInitStruct.FMC_ReadWriteTimingStruct = &FMC_ReadWriteTimingStruct;
	//读写同样时序，使用扩展模式时这个配置才有效
	FMC_NORSRAMInitStruct.FMC_WriteTimingStruct = &FMC_ReadWriteTimingStruct; 

	FMC_NORSRAMInit(&FMC_NORSRAMInitStruct);                //初始化FSMC配置
	FMC_NORSRAMCmd(FMC_NORSRAMInitStruct.FMC_Bank, ENABLE); //使能BANK
#endif
}




/*FSMC8080互斥锁*/
static ErrorStatus WHT_FSMC8080_BSP_Set_Mutex(void)
{
	if (WHT_LCD8080_Info.BSP_Mutex == RESET)//互斥锁关闭
	{
		WHT_LCD8080_Info.BSP_Mutex = SET;   //互斥锁打开
		return SUCCESS;
	}
	else
		return ERROR;
}
/*FSMC8080解锁*/
static void WHT_FSMC8080_BSP_Clr_Mutex(void)
{
	WHT_LCD8080_Info.BSP_Mutex = RESET;
}

#if (FSMC8080_Data_Width_bit == 8)
/*FSMC8080写命令*/
static void WHT_FSMC8080_BSP_Write_Cmd(unsigned char cmd)
{
	*(volatile unsigned char*)FSMC8080_Write_CMD = cmd;
}
/*FSMC8080写数据*/
static void WHT_FSMC8080_BSP_Write_Data(const unsigned char* input_buf, unsigned int count)
{
	while (count--)
	{
		*(volatile unsigned char*)FSMC8080_Write_DATA = *input_buf;
		input_buf++;
	}
}
/*FSMC8080写缓存*/
static void WHT_FSMC8080_BSP_Write(unsigned char cmd, const unsigned char* input_buf, unsigned int count)
{
	WHT_FSMC8080_BSP_Write_Cmd(cmd);
	WHT_FSMC8080_BSP_Write_Data(input_buf, count);
}
/*FSMC8080读数据*/
static void WHT_FSMC8080_BSP_Read(unsigned char cmd, unsigned char* output_buf, unsigned int count)
{
	WHT_FSMC8080_BSP_Write_Cmd(cmd);
	while (count--)
	{
		*output_buf = *(volatile unsigned char*)FSMC8080_Read_DATA;
		output_buf++;
	}
}
#elif (FSMC8080_Data_Width_bit == 16)
/*FSMC8080写命令*/
static void WHT_FSMC8080_BSP_Write_Cmd(unsigned short cmd)
{
	*(volatile unsigned short*)FSMC8080_Write_CMD = cmd;
}
/*FSMC8080写数据*/
static void WHT_FSMC8080_BSP_Write_Data(const unsigned short* input_buf, unsigned int count)
{
	while (count--)
	{
		*(volatile unsigned short*)FSMC8080_Write_DATA = *input_buf;
		input_buf++;
	}
}
/*FSMC8080写缓存*/
static void WHT_FSMC8080_BSP_Write(unsigned short cmd, const unsigned short* input_buf, unsigned int count)
{
	WHT_FSMC8080_BSP_Write_Cmd(cmd);
	WHT_FSMC8080_BSP_Write_Data(input_buf, count);
}
/*FSMC8080读数据*/
static void WHT_FSMC8080_BSP_Read(unsigned short cmd, unsigned short* output_buf, unsigned int count)
{
	WHT_FSMC8080_BSP_Write_Cmd(cmd);
	while (count--)
	{
		*output_buf = *(volatile unsigned short*)FSMC8080_Read_DATA;
		output_buf++;
	}
}
#elif (FSMC8080_Data_Width_bit == 32)
/*FSMC8080写命令*/
static void WHT_FSMC8080_BSP_Write_Cmd(unsigned int cmd)
{
	*(volatile unsigned int*)FSMC8080_Write_CMD = cmd;
}
/*FSMC8080写数据*/
static void WHT_FSMC8080_BSP_Write_Data(const unsigned int* input_buf, unsigned int count)
{
	while (count--)
	{
		*(volatile unsigned int*)FSMC8080_Write_DATA = *input_buf;
		input_buf++;
	}
}
/*FSMC8080写缓存*/
static void WHT_FSMC8080_BSP_Write(unsigned int cmd, const unsigned int* input_buf, unsigned int count)
{
	WHT_FSMC8080_BSP_Write_Cmd(cmd);
	WHT_FSMC8080_BSP_Write_Data(input_buf, count);
}
/*FSMC8080读数据*/
static void WHT_FSMC8080_BSP_Read(unsigned int cmd, unsigned int* output_buf, unsigned int count)
{
	WHT_FSMC8080_BSP_Write_Cmd(cmd);
	while (count--)
	{
		*output_buf = *(volatile unsigned int*)FSMC8080_Read_DATA;
		output_buf++;
	}
}
#endif


/*FSMC8080注册API*/
void WHT_FSMC8080_BSP_Register(WHT_FSMC8080_BSP_t* bsp)
{
	if (WHT_LCD8080_Info.Mount_Count++ == 0)
	{
		WHT_FSMC8080_BSP_GPIO_Init();
		WHT_FSMC8080_BSP_Config();
	}
    
	bsp->WHT_Info          = &WHT_LCD8080_Info;
	bsp->WHT_Set_BSP_Mutex = WHT_FSMC8080_BSP_Set_Mutex;
	bsp->WHT_Clr_BSP_Mutex = WHT_FSMC8080_BSP_Clr_Mutex;
    bsp->WHT_Write_Cmd     = WHT_FSMC8080_BSP_Write_Cmd;
    bsp->WHT_Write_Data    = WHT_FSMC8080_BSP_Write_Data;
    bsp->WHT_Write         = WHT_FSMC8080_BSP_Write;
    bsp->WHT_Read          = WHT_FSMC8080_BSP_Read;
}
